package com.gitee.l0km.beanfilter.core.json;

import java.io.IOException;
import java.lang.reflect.Type;

import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.JavaBeanSerializer;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.gitee.l0km.beanfilter.core.CodecPhase;
import com.gitee.l0km.beanfilter.core.CodecScene;
import com.gitee.l0km.beanfilter.core.Filterable;
import com.gitee.l0km.beanfilter.core.IFilter;
import com.gitee.l0km.beanfilter.core.LocalSupplyFilter;
import com.gitee.l0km.beanfilter.core.RequestPhase;
import com.gitee.l0km.beanfilter.core.SupplyFilter;
import com.gitee.l0km.beanfilter.core.context.LocalContext;
import com.google.common.base.Supplier;

/**
 * dynamic field filter implementation of  FastJson {@link JavaBeanSerializer},<br>
 * MAVEN dependencies:
 * <pre>
 *		&lt;dependency&gt;
 *			&lt;groupId&gt;com.alibaba&lt;/groupId&gt;
 *			&lt;artifactId&gt;fastjson&lt;/artifactId&gt;
 *			&lt;version&gt;${fastjson.version}&lt;/version&gt;
 *			&lt;scope&gt;provided&lt;/scope&gt;
 *		&lt;/dependency&gt;
 * </pre>
 * 
 * @author guyadong
 *
 */
public class FastjsonFilterableSerializer extends JavaBeanSerializer implements PropertyFilter,com.alibaba.fastjson.serializer.ValueFilter,Filterable{
	private final LocalSupplyFilter localSupplyFilter;
	public FastjsonFilterableSerializer(Class<?> beanType) {
		super(beanType);
		this.localSupplyFilter = new LocalSupplyFilter(beanType, RequestPhase.SERIALIZING, CodecScene.FASTJSON);
		addFilter(this);
	}
	@Override
	public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
			throws IOException {
		try {
			LocalContext.enteringEnv(object, RequestPhase.SERIALIZING, CodecScene.FASTJSON);
			super.write(serializer, object, fieldName, fieldType, features);
		} finally {
			LocalContext.exitingEnv();
		}
	}
	protected SupplyFilter getSupplyFilter() {
		return localSupplyFilter.getSupplyFilter();
	}
	@Override
	public void injectFilter(Supplier<? extends IFilter> fieldFilterSupplier, Supplier<? extends IFilter> valueFilterSupplier, CodecPhase codecPhase){
		if(null != fieldFilterSupplier || null !=valueFilterSupplier) {
			SupplyFilter supplyFilter = SupplyFilter.combine2(fieldFilterSupplier,valueFilterSupplier);
			localSupplyFilter.setSupplyFilter(supplyFilter);
		}
	}
	@Override
	public boolean apply(Object object, String name, Object value) {
		return  getSupplyFilter().permit(getType(), name);
	}
	@Override
	public Object process(Object object, String name, Object value) {
		return  getSupplyFilter().process(getType(), name, value);
	}
	
	
}
